﻿using Dycox.Validation;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;

namespace Dycox.ComponentModel
{
    [DataContract]
    public class OperationContract : NotifyPropertyChanged
    {
        protected OperationContract()
        {

        }

        private string _operatorName;

        [
        RequiredValidator(true, ErrorMessage = "必须提供经办人姓名", Condition = "IsOperatorNameRequired"),
        DisplayName("经办人"),
        DefaultValue(null),
        DataMember(),
        ModelProperty(ModelPropertyUsage.Application, false)
        ]
        public string OperatorName
        {
            get { return this._operatorName; }
            set
            {
                if (_operatorName != value)
                {
                    this._operatorName = value;
                    SendPropertyChanged("OperatorName");
                }
            }
        }

        [Browsable(false)]
        public virtual bool IsOperatorNameRequired
        {
            get { return false; }
        }

        private string _comment;

        [
        DisplayName("备注"),
        DefaultValue(null),
        DataMember(EmitDefaultValue = false),
        RequiredValidator(true, Condition = "IsCommentRequired == true", ErrorMessage = "必须提供备注"),
        ModelProperty(ModelPropertyUsage.User)
        ]
        public string Comment
        {
            get { return _comment; }
            set
            {
                if (_comment != value)
                {
                    _comment = value;
                    SendPropertyChanged("Comment");
                }
            }
        }

        [Browsable(false)]
        public virtual bool IsCommentRequired
        {
            get { return false; }
        }

        [OnSerializing]
        private void OnSerializingValues(StreamingContext context)
        {
            _serializingStatus = SerializationStatus.Serializing;
            this.OnSerializing(context);
        }

        protected virtual void OnSerializing(StreamingContext context)
        {
        }

        [OnSerialized]
        private void OnSerializedValues(StreamingContext context)
        {
            this.OnSerialized(context);
            _serializingStatus = SerializationStatus.None;
        }

        protected virtual void OnSerialized(StreamingContext context)
        {
        }

        [OnDeserializing]
        private void OnDeserializingValues(StreamingContext context)
        {
            _serializingStatus = SerializationStatus.Deserializing;
            this.OnDeserializing(context);
        }

        protected virtual void OnDeserializing(StreamingContext context)
        {
        }

        [OnDeserialized]
        private void OnDeserializedValues(StreamingContext context)
        {
            this.OnDeserialized(context);
            _serializingStatus = SerializationStatus.None;
        }

        protected virtual void OnDeserialized(StreamingContext context)
        {
        }

        public string ToJson()
        {
            JsonSerializer js = new JsonSerializer();
            js.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;

            StringWriter sw = new StringWriter();

            using (sw)
            {
                js.Serialize(sw, this);
                return sw.ToString();
            }

        }

        public static T FromJson<T>(string jsonText)
            where T : OperationContract
        {
            if (jsonText == null)
                throw new ArgumentNullException("jsonText");

            JsonSerializer js = new JsonSerializer();

            using (JsonReader reader = new JsonTextReader(new StringReader(jsonText)))
            {
                reader.CloseInput = true;
                return js.Deserialize<T>(reader);
            }
        }

        private SerializationStatus _serializingStatus;
        [Browsable(false)]
        public SerializationStatus SerializingStatus
        {
            get { return _serializingStatus; }
        }


    }
}
